package com.tn.service.dwr;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.tn.bo.Attachment;
import com.tn.bo.Company;
import com.tn.bo.Currency;
import com.tn.bo.POHeader;
import com.tn.bo.UnitOfMeasure;
import com.tn.bo.UserProfile;
import com.tn.bo.XMLUtil;
import com.tn.dao.AttachmentDAO;
import com.tn.dao.CompanyDAO;
import com.tn.dao.PurchaseOrderDAO;
import com.tn.dao.SequenceDetails;
import com.tn.dao.SequenceGenerator;
import com.tn.dao.UserDAO;
import com.tn.util.MailService;
import com.tn.xfer.DwrResponse;

public class PurchaseOrdersDwr {
	
	
	
	private static Map<String,SequenceDetails> ordernumDetailsMap = null;
	
	static {
		ordernumDetailsMap = new HashMap<String, SequenceDetails>();
		ordernumDetailsMap.put("PURCHASE_ORDER", new SequenceDetails("PO","PO_SEQ"));
		ordernumDetailsMap.put("LINE_ITEM", new SequenceDetails("LI","LI_SEQ"));
		ordernumDetailsMap.put("LINE_SPLIT", new SequenceDetails("LS","LS_SEQ"));
	}
	
	public DwrResponse fetchPurchaseOrdersForCompany(String companyId, boolean asBuyer, boolean asSupplier){
		DwrResponse response = new DwrResponse("SEARCH_PO_BY_COMPANY",0);
		HashMap<String,List<POHeader>> retMap = new HashMap<String,List<POHeader>>();
		try {
			CompanyDAO cDao = new CompanyDAO();
			
			Company oc = cDao.findCompanyByCompanyId(companyId);

			PurchaseOrderDAO poDao = new PurchaseOrderDAO();
			if(asBuyer){
				List<POHeader> list = poDao.findPOHeaderByOrderCompany(companyId,true);
				if(list != null && !list.isEmpty()){
					for(POHeader h: list){
						Company c = null;
						if(StringUtils.isNotEmpty(h.getOrderSupplier())){
							c = cDao.findCompanyByCompanyId(h.getOrderSupplier());
							if(c != null){
								h.setClientNameText(c.getCompanyName());
							}else{
								h.setClientNameText(h.getOrderSupplier());
							}
						}else{
							h.setClientNameText("Not Available");
						}
						//new XMLUtil().printAsXML(h);	
					}
				}
				retMap.put("PO_SENT", list);
			}
			
			if(asSupplier){
				List<POHeader> list = poDao.findPOHeaderByOrderCompany(companyId,false);
				
				if(list == null || list.isEmpty()){
					list = poDao.findPOHeaderByOrderCompany(oc.getCompanyId(), false);
				}
				
				if(list != null && !list.isEmpty()){
					for(POHeader h: list){
						Company c =  null;
						
						if(StringUtils.isNotEmpty(h.getOrderCompany())){
							c = cDao.findCompanyByCompanyId(h.getOrderCompany());
							if(c != null){
								h.setClientNameText(c.getCompanyName());
							}else{
								h.setClientNameText(h.getOrderCompany());
							}
						}else{
							h.setClientNameText("Not Available");
						}
						
						//new XMLUtil().printAsXML(h);	
					}
				}
				retMap.put("PO_RECD",list);
			}
			response.setObjRespOrError(retMap);
		}catch(Exception ex){
			response.setObjRespOrError(ex);
			response.setRespCode(-1);
		}
		
		
		return response;
	}
	
	public DwrResponse getAutogeneratedOrderNumber(String type){
		DwrResponse response = new DwrResponse("AUTO_GEN_ORDER_NUM",0);
		try {
			SequenceDetails details = ordernumDetailsMap.get(type);
			String next = SequenceGenerator.getNextSequenceValue(details.getSeqName());
			response.setObjRespOrError(details.getPrefix() + next);
		}catch(Exception ex){
			response.setObjRespOrError(ex);
			response.setRespCode(-1);
		}
		return response;
	}
	
	public DwrResponse getAutogeneratedOrderNumberBlock(String type,int blockSize){
		DwrResponse response = new DwrResponse("AUTO_GEN_ORDER_NUM",0);
		try {
			List<String> numBlock = new ArrayList<String>();
			SequenceDetails details = ordernumDetailsMap.get(type);
			for(int i=0;i<blockSize; i++){
				String next = SequenceGenerator.getNextSequenceValue(details.getSeqName());
				numBlock.add(details.getPrefix() + next);
			}
			response.setObjRespOrError(numBlock);
		}catch(Exception ex){
			response.setObjRespOrError(ex);
			response.setRespCode(-1);
		}
		return response;
	}
	
	public DwrResponse findSupplierInformation(Map<String, String> supplierQueryArgs){
		DwrResponse response = new DwrResponse("FIND_SUPPLIER", 0);
		try{
			CompanyDAO cDao = new CompanyDAO();
			response.setObjRespOrError(cDao.findCompanyByFilters(supplierQueryArgs));
		}catch(Exception ex){
			response.setObjRespOrError(ex);
			response.setRespCode(-1);
		}
		
		return response;
	}
	
	public DwrResponse createOrSavePurchaseOrder(POHeader header, boolean isCreate){
		DwrResponse response = new DwrResponse("CREATE_SAVE_PO", 0);
		try{
			PurchaseOrderDAO poDao = new PurchaseOrderDAO();
			header.setLastModifiedBy(header.getOrderComposer());
			header.setLastModifiedDate(new Date());
			header = poDao.insertPOHeader(header);
			header.setOrderXml(XMLUtil.getPurchaseOrderXml(header));
			response.setObjRespOrError(header.getOrderNumber());
			if(isCreate){
				sendPOMail(header);
			} else{
				response.setObjRespOrError(header);
			}
		}catch(Exception ex){
			ex.printStackTrace();
			response.setObjRespOrError(ex);
			response.setRespCode(-1);
		}
		
		return response;
	}
	
	private void sendPOMail(POHeader header) throws Exception{
		
		String companyUniqueId = header.getOrderSupplier();
		UserDAO userDAO = new UserDAO();
		CompanyDAO companyDAO = new CompanyDAO();
		if(companyUniqueId != null && !"".equals(companyUniqueId)){
			Company company = companyDAO.findCompanyByCompanyId(companyUniqueId);
			if(company != null && company.getEmailPreferences() != null &&  company.getEmailPreferences().isPoreceived()){
				ArrayList<UserProfile> userProfileList = userDAO.getByProperty("companyId",company.getCompanyId());
				for(int i=0; i<userProfileList.size();i++){
					UserProfile userProfile = userProfileList.get(i);
					if(userProfile != null){
						String email = userProfile.getEmailAddress();
						if(email != null){
							MailService mailService = new MailService();
								mailService.sendPOReceMail(email, header); //receiver
						}
					}
				}
			}
		}
		
		String companyUniqueIdSender = header.getOrderCompany();
		if(companyUniqueIdSender != null && !"".equals(companyUniqueIdSender)){
			Company company = companyDAO.findCompanyByCompanyId(companyUniqueIdSender);
			if(company != null && company.getEmailPreferences() != null &&  company.getEmailPreferences().isPosent()){
				ArrayList<UserProfile> userProfileList = userDAO.getByProperty("companyId",company.getCompanyId());
				for(int i=0; i<userProfileList.size();i++){
					UserProfile userProfile = userProfileList.get(i);
					if(userProfile != null){
						String email = userProfile.getEmailAddress();
						if(email != null){
							MailService mailService = new MailService();
							mailService.sendPOSenderMail(email, header); //sender
						}
					}
				}
			}
		}
		
		//TODO: add condition for super user mail only and not all
		
	}
	
	public DwrResponse findCompanyById(String id){
		DwrResponse response = new DwrResponse("FIND_COMPANY", 0);
		try{
			CompanyDAO companyDAO = new CompanyDAO();
			Company company = companyDAO.findCompanyById(id);
			response.setObjRespOrError(company);
		}catch(Exception ex){
			ex.printStackTrace();
			response.setObjRespOrError(ex);
			response.setRespCode(-1);
		}
		return response;
	}
	
	public DwrResponse getAllUnitOfMeasures(){
		DwrResponse response = new DwrResponse("GET_ALL_UOM",0);
		try{
			PurchaseOrderDAO dao = new PurchaseOrderDAO();
			List<UnitOfMeasure> list = dao.getAllUnitOfMeasures();
			response.setObjRespOrError(list);
		}catch(Exception ex){
			ex.printStackTrace();
			response.setObjRespOrError(ex);
			response.setRespCode(-1);
		}
		return response;
	}
	
	public DwrResponse getAllCurrencyCodes(){
		DwrResponse response = new DwrResponse("GET_ALL_CURR",0);
		try{
			PurchaseOrderDAO dao = new PurchaseOrderDAO();
			List<Currency> list = dao.getAllCurrencyCodes();
			response.setObjRespOrError(list);
		}catch(Exception ex){
			ex.printStackTrace();
			response.setObjRespOrError(ex);
			response.setRespCode(-1);
		}
		return response;
	}
	
	public DwrResponse updatePO(String poId, ArrayList<String> newAttachmentList,ArrayList<String> newCommentsList, String updatedBy){
		DwrResponse response = new DwrResponse("UPDATE_PO",0);
		try{
			PurchaseOrderDAO poDAO = new PurchaseOrderDAO();
			POHeader po = poDAO.getLatestPOHeader(poId);
			
			if(po.getOrderAttachmentsId() != null ){
				po.getOrderAttachmentsId().addAll(newAttachmentList);
			}  else{
				po.setOrderAttachmentsId(newAttachmentList);
			}
			
			if(po.getOrderComments() != null ){
				po.getOrderComments().addAll(newCommentsList);
			}  else{
				po.setOrderComments(newCommentsList);
			}
			
			po.setVersionNumber(String.valueOf(Integer.parseInt(po.getVersionNumber()) + 1));
			po.setOrderUniqueId(null);
			po.setLastModifiedDate(new Date());
			po.setLastModifiedBy(updatedBy);
			poDAO.updatePOHeader(po);
			
			po = poDAO.getLatestPOHeader(poId);
			po = poDAO.populateItemsOnHeader(po);
			
			response.setObjRespOrError(po);
			} catch (Exception ex) {
				ex.printStackTrace();
				response.setObjRespOrError(ex);
				response.setRespCode(-1);
			}
				
		
		return response;
	}
	
	public DwrResponse cancelPO(String poId, String updatedBy){
		DwrResponse response = new DwrResponse("UPDATE_PO",0);
		try{
			PurchaseOrderDAO poDAO = new PurchaseOrderDAO();
			POHeader po = poDAO.getLatestPOHeader(poId);
			po.setLastModifiedDate(new Date());
			po.setLastModifiedBy(updatedBy);
			po.setCancel(true);
			poDAO.updatePOHeader(po);
	
			response.setObjRespOrError(po);
			} catch (Exception ex) {
				ex.printStackTrace();
				response.setObjRespOrError(ex);
				response.setRespCode(-1);
			}
				
		
		return response;
	}
	
	
	public DwrResponse getPOHistory(String poNum){
		DwrResponse response = new DwrResponse("PO_HISTORY",0);
		try{
			PurchaseOrderDAO poDAO = new PurchaseOrderDAO();
			response.setObjRespOrError(poDAO.getPOHistory(poNum));
		} catch (Exception ex) {
			ex.printStackTrace();
			response.setObjRespOrError(ex);
			response.setRespCode(-1);
		}
		
		return response;
	}
	
	// added by amit.
	public DwrResponse getAutogeneratedPaymentNumber(String type) {
		PaymentDwr dwr = new PaymentDwr();
		return dwr.getAutogeneratedPaymentNumber(type);
	}
	
	public DwrResponse getAttachmentDetails(Long attachmentId) {
		DwrResponse response = new DwrResponse("ATTACHMENT_DETAILS",0);		
		Attachment a = new AttachmentDAO().find(attachmentId);
		response.setObjRespOrError(a);
		return response;
	}
	
	public DwrResponse getAttachmentDetailsList(Long[] attachmentId) {
		DwrResponse response = new DwrResponse("ATTACHMENT_LIST_DETAILS",0);
		List<Attachment> attachments = new ArrayList<Attachment>();
		for(int i=0;i<attachmentId.length;i++){
		Attachment a = new AttachmentDAO().find(attachmentId[i]);
			attachments.add(a);
		}
		response.setObjRespOrError(attachments);
		return response;
	}
	
}
